package com.ruoyi.livedemo.service;

import com.ruoyi.livedemo.dto.FileMetadataResponse;
import com.ruoyi.livedemo.entity.Attachment;
import com.ruoyi.livedemo.mapper.AttachmentMapper;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.UUID;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

@Service
@RequiredArgsConstructor
public class FileStorageService {

    private final AttachmentMapper attachmentMapper;

    @Value("${app.storage.root-path:uploads}")
    private String rootPath;

    public Path resolveRoot() throws IOException {
        Path root = Paths.get(rootPath).toAbsolutePath().normalize();
        if (Files.notExists(root)) {
            Files.createDirectories(root);
        }
        return root;
    }

    @Transactional
    public FileMetadataResponse store(Long userId, MultipartFile file, String description) {
        if (file == null || file.isEmpty()) {
            throw new IllegalArgumentException("请先选择需要上传的文件");
        }
        String original = StringUtils.hasText(file.getOriginalFilename())
                ? StringUtils.cleanPath(file.getOriginalFilename())
                : "";
        // 使用日期目录分层并结合 UUID 命名，方便管理同时避免重复
        String extension = "";
        int dot = original.lastIndexOf('.');
        if (dot >= 0) {
            extension = original.substring(dot);
        }
        String subDir = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy/MM"));
        String filename = UUID.randomUUID().toString().replace("-", "") + extension;
        try {
            Path root = resolveRoot();
            Path targetDir = root.resolve(subDir);
            Files.createDirectories(targetDir);
            Path targetFile = targetDir.resolve(filename);
            Files.copy(file.getInputStream(), targetFile, StandardCopyOption.REPLACE_EXISTING);

            Attachment attachment = new Attachment();
            attachment.setUserId(userId);
            attachment.setFilePath(subDir.replace('\\', '/') + "/" + filename);
            attachment.setMediaType(file.getContentType());
            attachment.setSizeBytes(file.getSize());
            attachment.setDescription(description);
            attachmentMapper.insert(attachment);

            return new FileMetadataResponse(
                    attachment.getId(),
                    attachment.getFilePath(),
                    attachment.getMediaType(),
                    attachment.getSizeBytes(),
                    attachment.getCreatedAt()
            );
        } catch (IOException e) {
            throw new RuntimeException("保存文件失败：" + e.getMessage(), e);
        }
    }

    public Attachment findMetadata(Long userId, Long attachmentId) {
        Attachment attachment = attachmentMapper.findByIdAndUser(attachmentId, userId);
        if (attachment == null) {
            throw new IllegalArgumentException("未找到对应的文件信息");
        }
        return attachment;
    }

    public Resource loadAsResource(Long userId, Long attachmentId) {
        Attachment attachment = findMetadata(userId, attachmentId);
        try {
            Path root = resolveRoot();
            Path filePath = root.resolve(attachment.getFilePath()).normalize();
            if (Files.notExists(filePath)) {
                throw new IllegalArgumentException("文件不存在或已被删除");
            }
            return new FileSystemResource(filePath);
        } catch (IOException e) {
            throw new RuntimeException("读取文件失败", e);
        }
    }
}
